package com.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.util.httpUtil.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.*;

import static java.time.temporal.TemporalAdjusters.firstInMonth;

/**
 *
 * 判断是否是节假日，工具类
 *
 *
 *
 * @Author
 * @Date 2024/2/23 16:05
 */
@Slf4j
public class HolidayUtil2 {

    public static void main(String[] args) {
        /*try {

            String workingDay = isWorkingDay("2024-04-23");
            System.out.println(" 是否假期:" +workingDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }


            // 获取每一个星期天
            // 创建代表一年中第一天的LocalDate对象。
            int year = 2024;
            LocalDate now = LocalDate.of(year, Month.JANUARY, 1);
            // 查找一年中的第一个星期日
            LocalDate sunday = now.with(firstInMonth(DayOfWeek.SUNDAY));

            do {
                // 通过将Period.ofDays(7)添加到当前星期日来循环获取每个星期日。
                System.out.println(sunday.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)));
                sunday = sunday.plus(Period.ofDays(7));
            } while (sunday.getYear() == year);
*/

        analyticReturnHoliday("2024");


    }

    /**
     * @Author chl
     * @Description 解析返回假期
     * @Date 10:02 2024/4/30
     * @param year 年份
     * @return response response
     **/
    public static void analyticReturnHoliday(String year) {
        //免费api地址，获取某年假日不带周末

        ArrayList<Object> list = new ArrayList<>();

        HashMap<String, Object> map1 = new HashMap<>();
        String format="https://timor.tech/api/holiday/year/%s?type=Y&week=Y";
        String httpUrl = String.format(format, year);
        try {
            String s = HttpUtils.doGetForData(httpUrl);
            Map<String,Map<String,Map<String,Object>>> map = JSON.parseObject(s, Map.class);
            Map<String,Map<String,Object>> holiday = map.get("holiday");
            for (String time : holiday.keySet()) {
                // 日期对象
                Map<String, Object> timeObject = holiday.get(time);

                // 是否放假
                Boolean holiday2 = (Boolean) timeObject.get("holiday");

                if (holiday2) {
                    // 获取日期
                    Object dateTime = timeObject.get("date");
                    list.add(dateTime);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(" :" + JSON.toJSONString(list));

    }


    /**
     * 免费的节假日API，拼接年可获取对应年份数据
     * get请求 https://timor.tech/api/holiday/year/2024
     */


    static Map<String,List<String>> holiday =new HashMap<>();       //假期
    static Map<String,List<String>> extraWorkDay =new HashMap<>();  //调休日

    //判断是否为节假日

    /**
     *
     * @param time 日期参数 格式‘yyyy-MM-dd’，不传参则默认当前日期
     * @return  返回值 :  0 上班 1周末 2节假日
     */
    public static String isWorkingDay(String time) throws ParseException {
        Date parse = null;
        //为空则返回当前时间
        if (StringUtils.isNotBlank(time)){
            SimpleDateFormat getYearFormat = new SimpleDateFormat("yyyy-MM-dd");
            parse = getYearFormat.parse(time);
        }else {
            parse = new Date();
        }
        String newDate  = new SimpleDateFormat("yyyy").format(parse);

        //判断key是否有参数年份
        if(!holiday.containsKey(newDate)){
            String holiday = getYearHoliday(newDate);
            if ("No!".equals(holiday)){
                return "该年份未分配日期安排！";
            }
        }
        //得到日期是星期几
        Date date = formatStringToDate(time, false);
        // Calendar.getInstance()获取一个Calendar实例
        Calendar calendar = Calendar.getInstance();
        // 设置日期
        calendar.setTime(date);
        // 获取星期
        int weekday = getDayOfWeek(calendar);


        // 是否是节假日
        if(holiday.get(newDate).contains(time)){
            return "2";
        }else if(extraWorkDay.get(newDate).contains(time)){     //是否为调休
            return "0";
        }else if(weekday == Calendar.SATURDAY || weekday == Calendar.FRIDAY){   //是否为周末
            return "1";
        }else{
            return "0";
        }
    }

    /**
     *
     * @param date 日期参数 格式‘yyyy’，不传参则默认当前日期
     * @return
     */
    public static String getYearHoliday(String date) throws ParseException {

        //免费api地址，获取某年假日不带周末
        String httpUrl="https://timor.tech/api/holiday/year/"+date;

        // 获取某年假日带周末,调休等
        // https://timor.tech/api/holiday/year/2024?type=Y&week=Y

        /*
        * 返回实例：holiday=true为放假，false为上班
        *   {
            "code": 0,
            "holiday": {
                "01-01": {
                    "holiday": true,
                    "name": "元旦",
                    "wage": 3,
                    "date": "2024-01-01",
                    "rest": 1
                },
                "01-06": {
                    "holiday": true,
                    "name": "周六",
                    "wage": 2,
                    "date": "2024-01-06"
                },
                "01-07": {
                    "holiday": true,
                    "name": "周日",
                    "wage": 2,
                    "date": "2024-01-07"
                },
                "01-13": {
                    "holiday": true,
                    "name": "周六",
                    "wage": 2,
                    "date": "2024-01-13"
                },
                "01-14": {
                    "holiday": true,
                    "name": "周日",
                    "wage": 2,
                    "date": "2024-01-14"
                },
                "01-20": {
                    "holiday": true,
                    "name": "周六",
                    "wage": 2,
                    "date": "2024-01-20"
                },
                "01-21": {
                    "holiday": true,
                    "name": "周日",
                    "wage": 2,
                    "date": "2024-01-21"
                },
                "01-27": {
                    "holiday": true,
                    "name": "周六",
                    "wage": 2,
                    "date": "2024-01-27"
                },
                "01-28": {
                    "holiday": true,
                    "name": "周日",
                    "wage": 2,
                    "date": "2024-01-28"
                },
                "02-03": {
                    "holiday": true,
                    "name": "周六",
                    "wage": 2,
                    "date": "2024-02-03"
                },
                "02-04": {
                    "holiday": false,
                    "name": "春节前补班",
                    "wage": 1,
                    "after": false,
                    "target": "春节",
                    "date": "2024-02-04",
                    "rest": 19
                },
                "02-10": {
                    "holiday": true,
                    "name": "初一",
                    "wage": 3,
                    "date": "2024-02-10",
                    "rest": 25
                },
                "02-11": {
                    "holiday": true,
                    "name": "初二",
                    "wage": 3,
                    "date": "2024-02-11",
                    "rest": 1
                },
                "02-12": {
                    "holiday": true,
                    "name": "初三",
                    "wage": 3,
                    "date": "2024-02-12",
                    "rest": 1
                },
                "02-13": {
                    "holiday": true,
                    "name": "初四",
                    "wage": 2,
                    "date": "2024-02-13",
                    "rest": 1
                }]
        *
        * */
        BufferedReader reader = null;
        String result = null;
        // 用于存储返回的年份节假日数据
        StringBuffer sbf = new StringBuffer();

        try {
            // 创建url对象
            URL url = new URL(httpUrl);
            // 使用openConnection方法创建了一个URLConnection对象
            URLConnection connection = url.openConnection();
            // 设置请求头
            connection.setRequestProperty("User-Agent", "Mozilla/4.76");
            connection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
            /**
             * 使用getInputStream方法获取输入流，这个输入流可以用来读取从URL地址返回的数据，
             * 可能是HTML内容、JSON数据或其他类型的信息。
             * 具体取决于URL地址所指向的资源类型。
             */
            InputStream is = connection.getInputStream();
            // BufferedReader创建字节流对象，InputStreamReader将字节流转换为字符流，编码为utf8
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));

            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead); // 将每行内容追加到sbf字符串变量中
                sbf.append("\r\n");  // 手动添加换行符
            }
            reader.close();  // 关闭流

            //字符串转json
            JSONObject json = JSON.parseObject(sbf.toString());
            //根据holiday字段获取jsonObject内容
            JSONObject holiday = json.getJSONObject("holiday");
            if (holiday.size() == 0){
                return "No!";
            }
            List hoList = new ArrayList<>();
            List extraList = new ArrayList<>();
            for (Map.Entry<String, Object> entry : holiday.entrySet()) {
                // 读取字符的值，并转换成字符串
                String value = entry.getValue().toString();
                // 将字符串改为json格式
                JSONObject jsonObject = JSONObject.parseObject(value);
                // 获取是否为假日（是为true，不是为false）
                String hoBool = jsonObject.getString("holiday");
                // 获取时间
                String extra = jsonObject.getString("date");
                //判断不是假期后调休的班
                if(hoBool.equals("true")){
                    hoList.add(extra);
                    // 添加假期
                    HolidayUtil2.holiday.put(date,hoList);
                }else {
                    extraList.add(extra);
                    // 添加调休日
                    HolidayUtil2.extraWorkDay.put(date,extraList);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 功能：获取String日期对应的时间
     * isTotal = false ;yyyy-MM-dd格式限定
     * isTotal = true ;yyyy-MM-dd hh-mm-ss格式限定
     */
    public static Date formatStringToDate(String base, Boolean isTotal) {
        // 是否包含时间部分
        String format = isTotal ? "yyyy-MM-dd HH-mm-ss" : "yyyy-MM-dd";
        // 格式化字符串
        DateFormat df = new SimpleDateFormat(format);
        Date baseTime;
        try {
            // 设定日期
            baseTime = df.parse(base);
        } catch (Exception e) {
            return null;
        }
        return baseTime;
    }


    /**
     * 获得本日星期数,星期一:1,星期日:7 如果传入null则默认为本日
     *
     * @return
     */
    public static int getDayOfWeek(Calendar calendar) {
        int today;
        if (calendar != null) {
            today = calendar.get(Calendar.DAY_OF_WEEK);
        } else {
            today = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
        }
        if (today == 1)
            return 7;
        else
            return today - 1;
    }
}
